package com.hczt.xhminiapp.adminapi.modules.system.service;

import com.hczt.xhminiapp.adminapi.modules.system.vo.AllotMenu;
import com.hczt.xhminiapp.adminapi.modules.system.vo.SysRoleQuery;
import com.hczt.xhminiapp.db.entity.SysPermission;
import com.hczt.xhminiapp.db.entity.SysRole;
import com.hczt.xhminiapp.db.entity.SysRole_;
import com.hczt.xhminiapp.db.repository.SysPermissionRepository;
import com.hczt.xhminiapp.db.repository.SysRoleRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 红创-马海强
 * @date 2019-03-13 14:55
 * @description 系统角色业务类
 */
@Service
public class SysRoleService {

    @Resource
    private SysRoleRepository sysRoleRepository;
    @Resource
    private SysPermissionRepository sysPermissionRepository;
    @Resource
    private SysPermissionService sysPermissionService;

    public Page<SysRole> findSysRoles(SysRoleQuery query, Pageable page) {
        Pageable pageable = new PageRequest(page.getPageNumber(), page.getPageSize(), new Sort(Sort.Direction.DESC, "createTime"));
        return sysRoleRepository.findAll(build(query), pageable);
    }

    private Specification<SysRole> build(SysRoleQuery query) {
        return (root, criteriaQuery, builder) -> {
            Predicate predicate = builder.conjunction();
            if (query.getEnable() != null) {
                predicate = builder.and(predicate, builder.equal(root.get(SysRole_.enabled), query.getEnable()));
            }
            if (!StringUtils.isEmpty(query.getSearch())) {
                String search = "%" + query.getSearch() + "%";
                Predicate likeTitle = builder.like(root.get(SysRole_.roleName), search);
                Predicate likeCode = builder.like(root.get(SysRole_.roleCode), search);
                predicate = builder.and(predicate, builder.or(likeTitle, likeCode));
            }
            return predicate;
        };
    }

    public SysRole findSysRoleDetail(String roleId){
        return sysRoleRepository.findById(roleId).get();
    }

    public void save(SysRole sysRole) {
        sysRole.setCreateTime(new Date());
        sysRoleRepository.save(sysRole);
    }

    public void update(SysRole roleInfo) {
        SysRole sysRole = sysRoleRepository.findById(roleInfo.getRoleId()).get();
        sysRole.setRoleName(roleInfo.getRoleName());
        sysRole.setRoleCode(roleInfo.getRoleCode());
        sysRole.setEnabled(roleInfo.getEnabled());
        sysRoleRepository.save(sysRole);
    }

    public void remove(String roleId) {
        sysRoleRepository.deleteById(roleId);
    }

    public List<SysPermission> findSysRoleMenus(String roleId) {
        List<SysPermission> allMenus = sysPermissionRepository.findByEnabledTrueOrderBySortAsc();
        SysRole role = sysRoleRepository.findById(roleId).get();
        List<SysPermission> selectMenus = allMenus.stream().map(t -> selectedMenu(t, role.getPermissionList())).collect(Collectors.toList());
        return sysPermissionService.menuListToTree(null, selectMenus);
    }

    private SysPermission selectedMenu(SysPermission permission, List<SysPermission> roleMenus) {
        List<SysPermission> menus = roleMenus.stream().filter(m -> m.getPermissionId().equals(permission.getPermissionId())).collect(Collectors.toList());
        permission.setSelected(!menus.isEmpty());
        return permission;
    }

    public void allotMenu(AllotMenu allotMenu) {
        List<SysPermission> permissions = new LinkedList<>();
        if (!allotMenu.getPermissionIds().isEmpty()) {
            permissions = sysPermissionRepository.findByPermissionIdIn(allotMenu.getPermissionIds());
        }
        SysRole sysRole = sysRoleRepository.findById(allotMenu.getRoleId()).get();
        sysRole.setPermissionList(permissions);
        sysRoleRepository.save(sysRole);
    }
}
